/*
 *  System0039.cpp
 *  SoundController0002
 *
 *  Created by jiro on 11/09/14.
 *  Copyright 2011 jiro music. All rights reserved.
 *
 */

#include "System0039.h"

using namespace ::sc::hs;
using namespace std;

namespace sc
{
namespace system0039
{

	::sc::hs::SoundList System0039::soundList[ ::sc::Note::NoteIdCount ];
	
	bool System0039::isDirty = true;

	void System0039::GetConcreteNotesFrom( const AbstractNote& abstractNote, std::vector< HarmonicSound >& harmonicSounds )
	{
		GenerateSoundListIfNeeded();
		SoundList& sounds = soundList[ Note::GetNoteIdFrom( abstractNote.GetGenerateMidiNumber() ) ];
		sounds.FindNoteWhereMidiNumber( abstractNote.GetMidiNumber(), harmonicSounds );
	}
	
	void System0039::GenerateSoundListIfNeeded()
	{
		if ( not isDirty )
		{
			return;
		}

		::sc::Note::MidiNumber number = ::sc::Note::E0;
		for ( int i = 0; i < ::sc::Note::NoteIdCount; i++ )
		{
			soundList[ ::sc::Note::GetNoteIdFrom( number ) ].push_back( ::sc::hs::Sound( ::sc::hs::Sound::SingleSineWave, number ) );
			number = static_cast< ::sc::Note::MidiNumber >( number + 1 );
		}
		isDirty= false;
	}

	void System0039::OutputFile( const AbstractRegion& region, const std::string& path, int repeatCount )
	{
		for ( int i = 0, count = region.GetConcreteRegionCount(); i < count; i++ )
		{
			AudioRecorder32 recorder( 2, 1 );
			ConcreteRegion concreteRegion;
			std::vector< std::vector< std::vector< const ::sc::SoundElement32* > > > region0;
			std::vector< std::vector< std::vector< const ::sc::SoundElement32* > > > region1;

			region.GetConcreteRegion( i, AbstractRegion::LeftAlignment, concreteRegion );
//			region.GetConcreteRegion( i, AbstractRegion::CenterAlignment, concreteRegion );
//			region.GetConcreteRegion( i, AbstractRegion::RightAlignment, concreteRegion );
			concreteRegion.ToSoundElements( region0, region1 );

			if ( path.find( "exsample001b" ) != std::string::npos and ( i == 5 ) )
			{
//				cout << i << "\n" << concreteRegion.ToString() << endl;
			}
//			cout << region.ToString() << endl;
//			cout << concreteRegion.ToString() << endl;

			double time = 0.0;
			stringstream ss;
			ss << path << "-" << i << ".wav";
			Record( recorder, time, concreteRegion, repeatCount );
			recorder.OutputAudioFile( ss.str() );
		}
	}

	void System0039::Record( AudioRecorder32& recorder, double& startTime, const ConcreteRegion& region, int repeatCount )
	{
		std::vector< std::vector< std::vector< const ::sc::SoundElement32* > > > region0;
		std::vector< std::vector< std::vector< const ::sc::SoundElement32* > > > region1;
		double time;

		region.ToSoundElements( region0, region1 );
		for ( int l = 0; l < repeatCount; l++ )
		{
			for ( int j = 0, lineCount = region0.size(); j < lineCount; j++ )
			{
				time = startTime;
				for ( int k = 0, noteCount = region0.at( j ).size(); k < noteCount; k++ )
				{
					recorder.Record( 0, 0, time, region0.at( j ).at( k ), 0.4, 0.6 );
					recorder.Record( 0, 0, time, region1.at( j ).at( k ), 0.6, 0.4 );
					time += region.at( j ).at( k ).GetDuration();
				}
			}
			startTime += region.GetDuration();
		}
	}

}
}
